package com.samsung.handler;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.exception.ZipExceptionConstants;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class ZipHandler {
	public ZipHandler() {
	}

	/**
	 * 
	 * @param des
	 *            destination location
	 * @param source
	 *            source file
	 * @param password
	 *            null/string
	 */
	public static void zipCompress(String des, String source, String password) {
		try {
			File sourceFile = new File(source);
			String desPath = des
					+ "/"
					+ sourceFile.getName().substring(0,
							sourceFile.getName().lastIndexOf(".")) + ".zip";
			System.out.println("DESPATH: " + desPath);
			// Initiate ZipFile object with the path/name of the zip file.
			File desFile = new File(desPath);
			if (desFile.exists()) {
				desFile.deleteOnExit();
			}

			ZipFile zipFile = new ZipFile(desPath);

			// Initiate Zip Parameters which define various properties such
			// as compression method, etc.
			ZipParameters parameters = new ZipParameters();

			// set compression method to store compression
			parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);

			// Set the compression level
			parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

			if (password != null) {
				parameters.setEncryptFiles(true);
				parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
				parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
				parameters.setPassword(password);
			}

			parameters.setIncludeRootFolder(false);
			// Add folder to the zip file
			if (sourceFile.isDirectory())
				zipFile.addFolder(sourceFile, parameters);
			else
				zipFile.addFile(sourceFile, parameters);

		} catch (ZipException e) {
			e.printStackTrace();
		}

	}

	public static void zipCompress(String des, ArrayList<String> srcFiles,
			String password) {
		try {
			File sourceFile = new File(srcFiles.get(0));
			String desPath = des
					+ "/"
					+ sourceFile.getName().substring(0,
							sourceFile.getName().lastIndexOf(".")) + ".zip";
			System.out.println("DESPATH: " + desPath);
			// Initiate ZipFile object with the path/name of the zip file.
			File desFile = new File(desPath);
			if (desFile.exists()) {
				desFile.deleteOnExit();
			}

			ZipFile zipFile = new ZipFile(desPath);

			// Initiate Zip Parameters which define various properties such
			// as compression method, etc.
			ZipParameters parameters = new ZipParameters();

			// set compression method to store compression
			parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);

			// Set the compression level
			parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

			if (password != null) {
				parameters.setEncryptFiles(true);
				parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
				parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
				parameters.setPassword(password);
			}

			parameters.setIncludeRootFolder(false);
			File f = new File("/");
			// Add folder to the zip file
			for (String s : srcFiles) {
				f = new File(s);
				if (f.isDirectory())
					zipFile.addFolder(f, parameters);
				else
					zipFile.addFile(f, parameters);
			}
		} catch (ZipException e) {
			e.printStackTrace();
		}

	}

	public static void deCompress(String zipFile, String dest, String passwd)
			throws ZipException {
		ZipFile zFile = new ZipFile(zipFile);
		if (!zFile.isValidZipFile()) {
			throw new ZipException("this is an broken zip file.");
		}
		File destDir = new File(dest);
		if (destDir.isDirectory() && !destDir.exists()) {
			destDir.mkdir();
		}
		if (zFile.isEncrypted()) {
			zFile.setPassword(passwd);
		}
		zFile.extractAll(dest);
	}

	/**
	 * check if this file requires password
	 * 
	 * @param zipFile
	 * @return
	 * @throws ZipException
	 */
	public static boolean isPassword(String zipFile) throws ZipException {
		ZipFile zFile = new ZipFile(zipFile);
		if (zFile.isEncrypted()) {
			return true;
		} else
			return false;
	}

	public static boolean verify(String filePath, String _passwd) {
		boolean c = true;
		try {
			ZipFile zipFile = new ZipFile(new File(filePath));
			if (zipFile.isEncrypted()) {
				zipFile.setPassword(_passwd);
			}
			List<FileHeader> fileHeaders = zipFile.getFileHeaders();
			for (FileHeader fileHeader : fileHeaders) {
				try {
					InputStream is = zipFile.getInputStream(fileHeader);
					byte[] b = new byte[1024];
					while (is.read(b) != -1) {
						return c;
					}
					is.close();
				} catch (ZipException e) {
					if (e.getCode() == ZipExceptionConstants.WRONG_PASSWORD) {
						System.out.println("Wrong password");
						c = false;
					} else {
						e.printStackTrace();
					}
				} catch (IOException e) {
					System.out.println("Most probably wrong password.");
					e.printStackTrace();
					c = false;
				}
			}
		} catch (Exception e) {
			System.out.println("Some other exception occurred");
			e.printStackTrace();
		}
		return c;
	}
}
